package cn.lazyturtle.bugpush.service.impl;

import cn.lazyturtle.bugpush.service.BugPushCallBackService;
import cn.lazyturtle.bugpush.service.dingdingcallback.DingDingCallBackHandler;
import cn.lazyturtle.bugpush.service.dingdingcallback.DingDingCallBackHandlerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Objects;


/**
 * <p>
 * AbstractBugPush :
 * </p>
 *
 * @author cwh
 * @since 2021-10-25
 */
@Component
@Slf4j
public class BugPushCallBackServiceImpl implements BugPushCallBackService {

    @Value("${ding-talk.appKey}")
    private String appKey;
    @Value("${ding-talk.aesKey}")
    private String encodingAesKey;
    @Value("${ding-talk.token}")
    private String token;

    @Override
    public Object  callback(String signature, Long timeStamp, String nonce, JSONObject encrypt){
        String params = "signature:" + signature + " timestamp:" + timeStamp + " nonce:" + nonce + " encrypt:" + encrypt;
        try {
            log.info("begin callback:" + params);
            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(token, encodingAesKey, appKey);

            // 从post请求的body中获取回调信息的加密数据进行解密处理
            String encryptStr = encrypt.getString("encrypt");
            String plainText = dingTalkEncryptor.getDecryptMsg(signature, timeStamp.toString(), nonce, encryptStr);
            JSONObject callBackContent = JSON.parseObject(plainText);

            // 根据回调事件类型做不同的业务处理
            String eventType = callBackContent.getString("EventType");
            DingDingCallBackHandler dingDingCallBackHandler = DingDingCallBackHandlerFactory.getInvokeStrategy(eventType);
            if (Objects.nonNull(dingDingCallBackHandler)){
                // 存在对应的回调处理器
                dingDingCallBackHandler.dealEvent(callBackContent);
            }else {
                log.info("暂不处理的回调,callBackContent:{},",callBackContent);
            }
            // 返回success的加密信息表示回调处理成功
            return dingTalkEncryptor.getEncryptedMap("success", timeStamp, nonce);
        } catch (Exception e) {
            //失败的情况，应用的开发者应该通过告警感知，并干预修复
            log.error("process callback fail." + params, e);
            return "fail";
        }finally {
            log.info("end callback");
        }
    }

}
